//
//  Turtle.cpp
//  NinjaTurtle
//
//  Created by Nguyen Tri Chung on 1/31/15.
//
//

#include "Turtle.h"

Turtle::Turtle() {
    this->moveState = MOVE_NONE;
    this->equipment = "";
    this->disappear = false;
    this->dead = false;
    this->jumping = false;
    this->performingSecondJump = false;
    this->insideTeleport = false;
    this->slashing = false;
    this->throwing = false;
    
    this->currentJumpHeight = 0;
    this->targetJumpHeight = -1;
    this->currentElapsedJumpTime = 0;
    this->jumpHeight = CONFIG_JUMP_HEIGHT;
    this->moveSpeed = CONFIG_MOVE_SPEED;
    this->lastStepY = -9999;
    this->currentThrowDelay = -1;
    
    this->initBody();
}

Turtle::~Turtle() {
}

void Turtle::initBody() {
    CSprite* turtleSprite = new CSprite(SPRITE_TYPE_MAIN);
    turtleSprite->initWithIdentifier(FRAME_TURTLE_IDLE);
    turtleSprite->bind(CStringUtil::getPattern(FRAME_TURTLE_IDLE));
    turtleSprite->bind(CStringUtil::getPattern(FRAME_TURTLE_FALL));
    turtleSprite->bind(CStringUtil::getPattern(FRAME_TURTLE_JUMP));
    turtleSprite->bind(CStringUtil::getPattern(FRAME_TURTLE_MOVE));
    turtleSprite->bind(CStringUtil::getPattern(FRAME_TURTLE_DIE));
    
    turtleSprite->bind(CStringUtil::getPattern(FRAME_TURTLE_IDLE_FAST));
    turtleSprite->bind(CStringUtil::getPattern(FRAME_TURTLE_FALL_FAST));
    turtleSprite->bind(CStringUtil::getPattern(FRAME_TURTLE_JUMP_FAST));
    turtleSprite->bind(CStringUtil::getPattern(FRAME_TURTLE_MOVE_FAST));
    
    turtleSprite->bind(CStringUtil::getPattern(FRAME_TURTLE_IDLE_STRENGTH));
    turtleSprite->bind(CStringUtil::getPattern(FRAME_TURTLE_FALL_STRENGTH));
    turtleSprite->bind(CStringUtil::getPattern(FRAME_TURTLE_JUMP_STRENGTH));
    turtleSprite->bind(CStringUtil::getPattern(FRAME_TURTLE_MOVE_STRENGTH));
    turtleSprite->bind(CStringUtil::getPattern(FRAME_TURTLE_PUSH_STRENGTH));
    
    turtleSprite->bind(CStringUtil::getPattern(FRAME_TURTLE_IDLE_WARRIOR));
    turtleSprite->bind(CStringUtil::getPattern(FRAME_TURTLE_FALL_WARRIOR));
    turtleSprite->bind(CStringUtil::getPattern(FRAME_TURTLE_JUMP_WARRIOR));
    turtleSprite->bind(CStringUtil::getPattern(FRAME_TURTLE_MOVE_WARRIOR));
    turtleSprite->bind(CStringUtil::getPattern(FRAME_TURTLE_THROW_WARRIOR));
    
    turtleSprite->bind(CStringUtil::getPattern(FRAME_TURTLE_IDLE_NINJA));
    turtleSprite->bind(CStringUtil::getPattern(FRAME_TURTLE_FALL_NINJA));
    turtleSprite->bind(CStringUtil::getPattern(FRAME_TURTLE_JUMP_NINJA));
    turtleSprite->bind(CStringUtil::getPattern(FRAME_TURTLE_MOVE_NINJA));
    turtleSprite->bind(CStringUtil::getPattern(FRAME_TURTLE_SLASH_NINJA));
    
    turtleSprite->bind(CStringUtil::getPattern(FRAME_TURTLE_IDLE_ANGEL));
    turtleSprite->bind(CStringUtil::getPattern(FRAME_TURTLE_FALL_ANGEL));
    turtleSprite->bind(CStringUtil::getPattern(FRAME_TURTLE_JUMP_ANGEL));
    turtleSprite->bind(CStringUtil::getPattern(FRAME_TURTLE_MOVE_ANGEL));
    
    this->getSprites()->pushBack(turtleSprite);
    
    // get action throw duration
    ActionInterval* throwAction = (ActionInterval*) turtleSprite->getAction(FRAME_TURTLE_THROW_WARRIOR, false);
    this->throwDelay = throwAction->getDuration();
    
    RectBody* rectBody = new RectBody(turtleSprite->getContentSize().width, turtleSprite->getContentSize().height);
    rectBody->setAnchorPoint(Point(0.5, 0));
    turtleSprite->setOOVector(Point(0, -turtleSprite->getContentSize().height / 2));
    CC_SAFE_RETAIN(rectBody);
    this->body = rectBody;
}

void Turtle::move(MoveState moveState) {
    if (this->disappear || this->dead) {
        return;
    }
    this->moveState = moveState;
    if (this->moveState == MOVE_LEFT) {
        this->body->setFlipX(true);
    } else if (this->moveState == MOVE_RIGHT) {
        this->body->setFlipX(false);
    }
}

bool Turtle::jump(float suddenHeight) {
    if (this->disappear || this->dead) {
        return false;
    }
    
    if (suddenHeight > 0) {
        this->targetJumpHeight = suddenHeight;
        this->currentElapsedJumpTime = 0;
        this->lastStepY = this->getPosition().y;
    } else {
        if (this->jumping) {
            if (this->equipment == EQUIPMENT_ANGEL && !this->performingSecondJump) {
                this->targetJumpHeight = this->jumpHeight;
                this->currentElapsedJumpTime = 0;
                this->lastStepY = this->getPosition().y;
                this->performingSecondJump = true;
            } else {
                return false;
            }
        }
    }
    this->jumping = true;
    
    if (this->targetJumpHeight == -1) {
        this->targetJumpHeight = this->jumpHeight;
    }
    return true;
}

void Turtle::update(float dt) {
    Obj::update(dt);
    if (this->moveState == MOVE_LEFT) {
        this->body->setVelocity(Point(-this->moveSpeed, 0));
    } else if (this->moveState == MOVE_RIGHT) {
        this->body->setVelocity(Point(this->moveSpeed, 0));
    } else {
        this->body->setVelocity(Point(0, 0));
    }
}

void Turtle::equip(const string& equipment) {
    this->equipment = equipment;
}

string Turtle::getStateDie() {
    return FRAME_TURTLE_DIE;
}

string Turtle::getStateSlash() {
    if (this->equipment == EQUIPMENT_NINJA) {
        return FRAME_TURTLE_SLASH_NINJA;
    }
    return "";
}

string Turtle::getStateThrow() {
    if (this->equipment == EQUIPMENT_WARRIOR) {
        return FRAME_TURTLE_THROW_WARRIOR;
    }
    return "";
}

string Turtle::getStatePush() {
    if (this->equipment == EQUIPMENT_STRENGTH) {
        return FRAME_TURTLE_PUSH_STRENGTH;
    }
    return "";
}

string Turtle::getStateFall() {
    if (this->equipment == EQUIPMENT_FAST) {
        return FRAME_TURTLE_FALL_FAST;
    }
    if (this->equipment == EQUIPMENT_STRENGTH) {
        return FRAME_TURTLE_FALL_STRENGTH;
    }
    if (this->equipment == EQUIPMENT_WARRIOR) {
        return FRAME_TURTLE_FALL_WARRIOR;
    }
    if (this->equipment == EQUIPMENT_NINJA) {
        return FRAME_TURTLE_FALL_NINJA;
    }
    if (this->equipment == EQUIPMENT_ANGEL) {
        return FRAME_TURTLE_FALL_ANGEL;
    }
    return FRAME_TURTLE_FALL;
}


string Turtle::getStateJump() {
    if (this->equipment == EQUIPMENT_FAST) {
        return FRAME_TURTLE_JUMP_FAST;
    }
    if (this->equipment == EQUIPMENT_STRENGTH) {
        return FRAME_TURTLE_JUMP_STRENGTH;
    }
    if (this->equipment == EQUIPMENT_WARRIOR) {
        return FRAME_TURTLE_JUMP_WARRIOR;
    }
    if (this->equipment == EQUIPMENT_NINJA) {
        return FRAME_TURTLE_JUMP_NINJA;
    }
    if (this->equipment == EQUIPMENT_ANGEL) {
        return FRAME_TURTLE_JUMP_ANGEL;
    }
    return FRAME_TURTLE_JUMP;
}

string Turtle::getStateMove() {
    if (this->equipment == EQUIPMENT_FAST) {
        return FRAME_TURTLE_MOVE_FAST;
    }
    if (this->equipment == EQUIPMENT_STRENGTH) {
        return FRAME_TURTLE_MOVE_STRENGTH;
    }
    if (this->equipment == EQUIPMENT_WARRIOR) {
        return FRAME_TURTLE_MOVE_WARRIOR;
    }
    if (this->equipment == EQUIPMENT_NINJA) {
        return FRAME_TURTLE_MOVE_NINJA;
    }
    if (this->equipment == EQUIPMENT_ANGEL) {
        return FRAME_TURTLE_MOVE_ANGEL;
    }
    return FRAME_TURTLE_MOVE;
}

string Turtle::getStateIdle() {
    if (this->equipment == EQUIPMENT_FAST) {
        return FRAME_TURTLE_IDLE_FAST;
    }
    if (this->equipment == EQUIPMENT_STRENGTH) {
        return FRAME_TURTLE_IDLE_STRENGTH;
    }
    if (this->equipment == EQUIPMENT_WARRIOR) {
        return FRAME_TURTLE_IDLE_WARRIOR;
    }
    if (this->equipment == EQUIPMENT_NINJA) {
        return FRAME_TURTLE_IDLE_NINJA;
    }
    if (this->equipment == EQUIPMENT_ANGEL) {
        return FRAME_TURTLE_IDLE_ANGEL;
    }
    return FRAME_TURTLE_IDLE;
}